﻿using System;
using System.Collections.Generic;
using System.Text;

namespace PW.Mini.SlepowronskiJ.Siec.Aktywacja
{

    /// <summary>
    /// Skalowalna sigmoidalna funkcja aktywacji
    /// </summary>
    /// <remarks>
    /// Definicja sigmoidalnej funkcji aktywacji
    /// <code>
    ///             alfa
    /// f(x) = -----------------   beta,alfa > 0
    ///         1 + e^(-beta*x)
    /// 
    /// f'(x) = alfa* beta * fsig(x) * ( 1 - fsig(x) )   
    /// </code>     
    /// </remarks>

    [Serializable]
    class SkalowalnaSigmidalnaFunkcjaAktywacji : SigmoidalnaFunkcjaAktywacji
    {
        /// <summary>
        /// parametr sigmoidy
        /// </summary>
        private double alfa = 4.0;


        /// <summary>
        /// pobiera i ustawia wartosc parametru alfa
        /// ( alfa musi byc dodatnia - ustawia sie 1 w przypadku niedodatniej wartosci )
        /// </summary>
        public double Alfa
        {
            get { return alfa; }
            set { alfa = (value > 0) ? value : 1.0; }
        }

        public SkalowalnaSigmidalnaFunkcjaAktywacji()
            : base()
        {
            nazwa = "Skalowalna sigmoida";
            rodzajPolarnosci = SKALOWANIE_UNIPOLARNE;
        }

        /// <summary>
        /// Clone the object.
        /// </summary>
        /// <returns>The cloned object.</returns>
        public override object Clone()
        {
            return new SkalowalnaSigmidalnaFunkcjaAktywacji();
        }

        /// <summary>
        /// <code>
        ///                 alfa
        /// f(x) = -----------------   beta,alfa > 0
        ///         1 + e^(-beta*x)
        /// </code>
        /// </summary>
        /// <param name="x">x</param>
        /// <returns>f(x)</returns>
        public override double WartoscFunkcji(double x)
        {
            return alfa * base.WartoscFunkcji(x);
        }

        /// <summary>
        /// <code>
        /// f'(x) = alfa* beta * fsig(x) * ( 1 - fsig(x) )   
        /// </code>
        /// </summary>
        /// <param name="x">x</param>
        /// <returns>f'(x)</returns>
        public override double WartoscPochodnejFunkcji(double x)
        {
            double y = base.WartoscFunkcji(x);
            return (alfa* beta * y * (1 - y));
        }

        /// <inheritdoc />
        public override double DerivativeFunction(double b, double y)
        {
            return WartoscPochodnejFunkcji(b);
        }
    }
}
